﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DataImporter.Models;
using System.Text.RegularExpressions;
using System.IO;

namespace DataImporter.Modules
{
    public partial class ucExamItems : UserControl
    {
        #region Fields

        /// <summary>
        /// 数据列表
        /// </summary>
        private List<ExamItemPackage> categories = null;
        private List<ExamItem> items = null;
        private List<ExamPackageWithItems> relations = null;
        private List<ExamPackageWithChoice> examPackageWithChoices = null;

        #endregion

        public ucExamItems()
        {
            InitializeComponent();
        }

        #region Methods

        /// <summary>
        /// 点击检查按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCheck_Click(object sender, EventArgs e)
        {
            if (ofdOpen.ShowDialog() != DialogResult.OK)
                return;
            var excels = ofdOpen.FileName.ToExcelList("触摸屏答题与体检项目参考2");
            var ss = new StringBuilder();
            excels.ForEach(c =>
            {
                if (Regex.IsMatch(c.C, @"^\D+\d$") && c.L.IsNullOrEmpty())
                    ss.AppendLine($"套餐：{c.C} 没有套餐聚合ID，行数：{excels.IndexOf(c) + 2}");

                if (!c.D.IsNullOrEmpty() && !int.TryParse(c.J, out var n))
                    ss.AppendLine($"编码：{c.A} 优先级不是数字：{c.J}");
                if (!c.A.IsNullOrEmpty() && !c.D.IsNullOrEmpty())
                    ss.AppendLine($"编码：{c.D} 和题目平行，行数：{excels.IndexOf(c) + 2}");

                if (!c.G.IsNullOrEmpty() && c.D.IsNullOrEmpty())
                    ss.AppendLine($"临床意义：{c.G} 编码等其他信息为空，行数：{excels.IndexOf(c) + 2}");

                if (!c.D.IsNullOrEmpty() && c.F.IsNullOrEmpty())
                    ss.AppendLine($"编码：{c.D} 价格为空，行数：{excels.IndexOf(c) + 2}");

                if (c.H.Contains("sex") && !c.H.Contains("'sex'"))
                    ss.AppendLine($"编码：{c.D} 规则有问题：{c.H}，行数：{excels.IndexOf(c) + 2}");
                try
                {
                    if (!c.H.IsNullOrEmpty())
                        DyncmicRuntime.Compute(c.H.Replace("age", "18"));
                }
                catch
                {
                    ss.AppendLine($"编码：{c.D} 规则无法通过运算：{c.H}");
                }
            });
            excels.Where(c => !c.D.IsNullOrEmpty()).GroupBy(c => c.D).ToList().ForEach(item =>
            {
                ss.AppendLine().AppendLine("编码：" + item.Key);
                var items = item.GroupBy(c => c.E);
                if (items.Count() > 1)
                    ss.AppendLine($" 名称不一样：{items.Select(c => c.Key).Joins("、")}");

                items = item.GroupBy(c => c.F);
                if (items.Count() > 1)
                    ss.AppendLine($"  价格不一样：{items.Select(c => c.Key).Joins("、")}");

                items = item.GroupBy(c => c.G);
                if (items.Count() > 1)
                    ss.AppendLine($" 临床意义不一样：{items.Select(c => c.Key).Joins("、")}");
            });
            this.rtbContent.Text = ss.ToString();
        }

        /// <summary>
        /// 点击分析按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAnalyze_Click(object sender, EventArgs e)
        {
            if (ofdOpen.ShowDialog() != DialogResult.OK)
                return;
            var excels = ofdOpen.FileName.ToExcelList("触摸屏答题与体检项目参考2");
            items = new List<ExamItem>();
            relations = new List<ExamPackageWithItems>();
            categories = new List<ExamItemPackage>();
            examPackageWithChoices = new List<ExamPackageWithChoice>();
            var lstChoices = new List<string>();
            var codes = new StringBuilder();
            var package = string.Empty;
            var packageUid = 0;
            foreach (var excel in excels)
            {
                if (!excel.A.IsNullOrEmpty())
                {
                    codes.Append($"{excel.A.Replace(" ", "")},");
                    continue;
                }
                if (codes.Length > 2)
                {
                    lstChoices.Clear();
                    lstChoices.AddRange(codes.ToString().Split(",".ToArray(), StringSplitOptions.RemoveEmptyEntries));
                    codes.Clear();
                }
                if (!excel.C.IsNullOrEmpty())
                {
                    package = excel.C;
                    if (excel.L.IsNullOrEmpty())
                        packageUid = 0;
                    else
                        packageUid = int.Parse(excel.L);
                }
                if (excel.D.IsNullOrEmpty())
                    continue;
                AddItem(new ExamItem
                {
                    Code = excel.D,
                    Name = excel.E,
                    Meaning = excel.G,
                    Required = !excel.N.IsNullOrEmpty(),
                    Price = float.Parse(excel.F),
                    ConflictItems = excel.K
                }, new ExamPackageWithItems
                {
                    Rule = excel.H,
                    PackageUID = packageUid,
                    Priority = int.Parse(excel.J),
                    Scope = excel.I.Equals("y", StringComparison.OrdinalIgnoreCase) ? 0 : excel.I.Equals("q", StringComparison.OrdinalIgnoreCase) ? 3 : excel.I.Equals("z", StringComparison.OrdinalIgnoreCase) ? 2 : 1,
                }, package, lstChoices);
            }
            this.dgvData.DataSource = null;
            this.dgvData.DataSource = items;
        }

        /// <summary>
        /// 处理推荐
        /// </summary>
        /// <param name="recommanded">要处理的推荐内容</param>
        /// <returns>结果</returns>
        private string HandleRecommanded(string recommanded)
        {
            return Regex.Replace(Regex.Replace(recommanded.Trim().Trim('\t', '。').TrimStart('£', '*', '¨'), "[¨£*]", "，"), "（\\d+）", "");
        }

        private void AddItem(ExamItem examItem, ExamPackageWithItems examItemRelation, string package, List<string> choices)
        {
            var category = this.categories.Find(c => c.Name == package);
            if (null == category)
                this.categories.Add(category = new ExamItemPackage
                {
                    Id = this.categories.Count + 1,
                    Name = package
                });
            var item = this.items.Find(c => c.Code == examItem.Code);
            if (null == item)
            {
                examItem.Id = this.items.Count + 1;
                this.items.Add(examItem);
                item = examItem;
            }
            examItemRelation.ItemId = item.Id;
            examItemRelation.PackageId = category.Id;
            choices.ForEach(code =>
            {
                if (!examPackageWithChoices.Any(c => c.ChoiceCode == code && c.PackageId == category.Id))
                    examPackageWithChoices.Add(new ExamPackageWithChoice
                    {
                        ChoiceCode = code,
                        PackageId = category.Id
                    });
            });
            this.relations.Add(examItemRelation);
        }

        /// <summary>
        /// 点击保存按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                var db = new DBContext();
                db.Db.DbMaintenance.TruncateTable<ExamItemPackage>();
                db.Db.DbMaintenance.TruncateTable<ExamItem>();
                db.Db.DbMaintenance.TruncateTable<ExamPackageWithItems>();
                db.Db.DbMaintenance.TruncateTable<ExamPackageWithChoice>();
                db.Db.GetSimpleClient<ExamPackageWithChoice>().InsertRange(examPackageWithChoices.ToArray());
                db.ExamItemPackageDB.InsertRange(categories.ToArray());
                db.ExamItemRelationDB.InsertRange(relations.ToArray());
                if (db.ExamItemDB.InsertRange(items.ToArray()))
                    MessageBox.Show("保存成功");
                else
                    MessageBox.Show("保存失败");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 获取所有数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGetAllData_Click(object sender, EventArgs e)
        {
            try
            {
                this.dgvData.DataSource = null;
                this.dgvData.DataSource = new DBContext().HDAARMDB.GetList();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 点击删除
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsmiDelete_Click(object sender, EventArgs e)
        {
            if (this.dgvData.SelectedRows?.Count == 0)
                return;
            if (MessageBox.Show("确定要删除吗？", "询问", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                return;
            var ids = this.dgvData.SelectedRows.OfType<DataGridViewRow>().Select(c => (dynamic)c.Cells["Id"].Value).ToArray();
            if (new DBContext().HDAARMDB.DeleteByIds(ids))
            {
                this.btnGetAllData_Click(null, null);
            }
        }

        /// <summary>
        /// 点击获取所有分类
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAllCategories_Click(object sender, EventArgs e)
        {
            this.categories = new DBContext().ExamItemPackageDB.GetList();
            this.dgvData.DataSource = null;
            this.dgvData.DataSource = this.categories;
        }

        private void btnShowItems_Click(object sender, EventArgs e)
        {
            this.dgvData.DataSource = null;
            this.dgvData.DataSource = this.items;
        }

        private void btnShowRelation_Click(object sender, EventArgs e)
        {
            this.dgvData.DataSource = null;
            this.dgvData.DataSource = this.relations;
        }

        private void btnShowPackage_Click(object sender, EventArgs e)
        {
            this.dgvData.DataSource = null;
            this.dgvData.DataSource = this.categories;
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            var db = new DBContext();
            var qs = db.VAQuestionDB.GetList();
            var ans = db.VAAnswerDB.GetList();
            var table = new DataTable();
            table.Columns.AddRange(new DataColumn[] {
                new DataColumn("Id", typeof(int)), new DataColumn("问题", typeof(string)),new DataColumn("分类",typeof(string)), new DataColumn("答案",typeof(string)), new DataColumn("分类名称", typeof(string)),new DataColumn("编码",typeof(string)),
                new DataColumn("分数",typeof(int)),
                new DataColumn("描述",typeof(string)),new DataColumn("体检项套餐编码", typeof(string)),
                new DataColumn("顺序",typeof(int)),new DataColumn("是否为单选",typeof(bool)),
                new DataColumn("是否必选",typeof(bool)), new DataColumn("子选项",typeof(string)),
                new DataColumn("规则",typeof(string)),new DataColumn("父ID",typeof(int))
            });

            foreach (var q in qs)
            {
                table.Rows.Add(q.Id, q.Name, null, null, q.Value, null, 0, null, null, q.Order, q.Radio, q.Required, q.PEItems, null, 0);
                var codes = q.PEItems.Split(',');
                var cs = ans.FindAll(c => c.ParentID == 0 && codes.Contains(c.Code));
                foreach (var c in cs)
                {
                    table.Rows.Add(c.Id, null, c.Name, null, null, c.Code, c.Score, c.Remark, c.PE, c.Order, false, false, null, c.Rule, c.ParentID);
                    foreach (var cc in ans.FindAll(d => d.ParentID == c.Id))
                        table.Rows.Add(cc.Id, null, null, cc.Name, null, cc.Code, cc.Score, cc.Remark, cc.PE, cc.Order, false, false, null, cc.Rule, cc.ParentID);
                }
            }
            table.SaveToExcel(Path.Combine(Application.StartupPath, "VA.xls"));
            MessageBox.Show("导出成功");
        }

        #endregion
    }
}
